package com.seeyon.apps.bense.common.domain;


import cn.hutool.core.collection.CollectionUtil;
import www.seeyon.com.utils.UUIDUtil;

import java.util.*;


public class Cap4Where {
    private final List<List<String>> groups = new ArrayList<>();

    private List<String> currentGroup = new ArrayList<>();

    private final Map<String, Object> parameters = new HashMap<>();

    private final List<String> orderByColumns = new ArrayList<>();

    public Map<String, Object> getParameters() {
        return parameters;
    }

    public static String toCamelCase(CharSequence name) {
        if (null == name) {
            return null;
        }

        String name2 = name.toString();
        if (name2.contains("_")) {
            int length = name2.length();
            StringBuilder sb = new StringBuilder(length);
            boolean upperCase = false;

            for (int i = 0; i < length; ++i) {
                char c = name2.charAt(i);
                if (c == '_') {
                    upperCase = true;
                } else if (upperCase) {
                    sb.append(Character.toUpperCase(c));
                    upperCase = false;
                } else {
                    sb.append(Character.toLowerCase(c));
                }
            }

            return sb.toString() + "_" + UUIDUtil.getUUIDLong();
        } else {
            return name2 + "_"  + UUIDUtil.getUUIDLong();
        }
    }

    public Cap4Where eq(String column, Object value) {
        if (value != null && !value.toString().isEmpty()) {
            initCurrentGroup();
            String param = toCamelCase(column);
            currentGroup.add(column + " = :" + param);
            parameters.put(param, value);
        }
        return this;
    }

    public Cap4Where gt(String column, Number value) {
        if (value != null) {
            initCurrentGroup();
            String param = toCamelCase(column);
            currentGroup.add(column + " > :" + param);
            parameters.put(param, value);
        }
        return this;
    }

    public Cap4Where ge(String column, Number value) {
        if (value != null) {
            initCurrentGroup();
            String param = toCamelCase(column);
            currentGroup.add(column + " >= :" + param);
            parameters.put(param, value);
        }
        return this;
    }

    public Cap4Where lt(String column, Number value) {
        if (value != null) {
            initCurrentGroup();
            String param = toCamelCase(column);
            currentGroup.add(column + " < :" + param);
            parameters.put(param, value);
        }
        return this;
    }

    public Cap4Where le(String column, Number value) {
        if (value != null) {
            initCurrentGroup();
            String param = toCamelCase(column);
            currentGroup.add(column + " <= :" + param);
            parameters.put(param, value);
        }
        return this;
    }

    public Cap4Where in(String column, Collection values) {
        if (values != null && !values.isEmpty()) {
            initCurrentGroup();
            String param = toCamelCase(column) + "s";
            String val = CollectionUtil.join(values, ",");
            currentGroup.add(column + " IN ( :" + param + ")");
            parameters.put(param, val);
        }
        return this;
    }

    public Cap4Where notIn(String column, Collection values) {
        if (values != null && !values.isEmpty()) {
            initCurrentGroup();
            String param = toCamelCase(column) + "s";
            String val = CollectionUtil.join(values, ",");
            currentGroup.add(column + " NOT IN ( :" + param + ")");
            parameters.put(param, val);
        }
        return this;
    }

    public Cap4Where like(String column, String value) {
        if (value != null && !value.isEmpty()) {
            initCurrentGroup();
            String param = toCamelCase(column);
            currentGroup.add(column + " LIKE :" + param);
            parameters.put(param, "%" + value + "%");
        }
        return this;
    }
    public Cap4Where notLike(String column, String value) {
        if (value != null && !value.isEmpty()) {
            initCurrentGroup();
            String param = toCamelCase(column);
            currentGroup.add(column + " NOT LIKE :" + param);
            parameters.put(param, "%" + value + "%");
        }
        return this;
    }

    public Cap4Where isNull(String column) {
        initCurrentGroup();
        currentGroup.add(column + " IS NULL");
        return this;
    }

    public Cap4Where notNull(String column) {
        initCurrentGroup();
        currentGroup.add(column + " IS NOT NULL");
        return this;
    }

    public Cap4Where orderByAsc(String column) {
        if (column != null && !column.isEmpty()) {
            orderByColumns.add(column + " ASC");
        }
        return this;
    }

    public Cap4Where orderByDesc(String column) {
        if (column != null && !column.isEmpty()) {
            orderByColumns.add(column + " DESC");
        }
        return this;
    }

    public Cap4Where or() {
        if (!currentGroup.isEmpty()) {
            groups.add(currentGroup);
            currentGroup = new ArrayList<>();
        }
        return this;
    }

    private void initCurrentGroup() {
        if (currentGroup == null) {
            currentGroup = new ArrayList<>();
        }
    }

    // 构建最终WHERE子句
    public String build() {
        StringBuilder sql = new StringBuilder();
        sql.append(buildWhere());
        buildOrderByClause(sql);
        return sql.toString();
    }

    public String buildWhere() {
        List<List<String>> allGroups = new ArrayList<>(groups);
        if (!currentGroup.isEmpty()) {
            allGroups.add(currentGroup);
        }

        if (allGroups.isEmpty()) {
            return "";
        }

        List<String> combined = new ArrayList<>();
        for (List<String> group : allGroups) {
            if (!group.isEmpty()) {
                combined.add("(" + String.join(" AND ", group) + ")");
            }
        }

        return combined.isEmpty() ? "" : " WHERE " + String.join(" OR ", combined);
    }

    private void buildOrderByClause(StringBuilder sql) {
        if (!orderByColumns.isEmpty()) {
            sql.append(" ORDER BY ")
                    .append(String.join(", ", orderByColumns));
        }
    }

    public Cap4Where clearAll(){
        parameters.clear();
        groups.clear();
        orderByColumns.clear();
        currentGroup.clear();
        return this;
    }

    public Cap4Where clearParameter(){
        parameters.clear();
        return this;
    }
}
